﻿using UnityEngine;
using System.Collections;

public class scBlockAction : MonoBehaviour {

	public const float blockStandardHP = 100.0f;
	public Sprite [] blockSprite = new Sprite[3];
	public GameObject blockCrash;
	
	enum BlockCondition
	{
		Perfect,
		Cracked,
		Poor,
		Wrecked,
		Broken,

		Count
	}

	private float blockHP = blockStandardHP;
	private bool isDamageSafe = true;
	private BlockCondition beforeBlockCondition = BlockCondition.Perfect;
	private BlockCondition currentBlockCondition = BlockCondition.Perfect;


	// Use this for initialization
	void Start () {
		Invoke("_VitalizeDamage", 1.0f);
	}
	
	// Update is called once per frame
	void Update () {
	}

	void OnCollisionEnter2D(Collision2D coll)
	{
		if (isDamageSafe)
		{
			return;
		}

		if (coll.gameObject.tag == "Bird")
		{
			return;
		}
		else if (coll.gameObject.tag == "Block" || coll.gameObject.tag == "Pig")
		{
			_DamageToAnothers(coll);
		}
		else
		{
			_SelfDamage();
		}
	}

	void ApplyDamage(float damage)
	{
		blockHP -= damage;

		_ApplyBlockCondition();
		_ApplyScore();
		_ApplyBlockEffect();

		beforeBlockCondition = currentBlockCondition;
	}

	void _VitalizeDamage()
	{
		isDamageSafe = false;
	}

	void _DamageToAnothers(Collision2D coll)
	{
		float hitDamage = Mathf.Max(blockHP / 2.0f, 1f);

		coll.gameObject.SendMessage("ApplyDamage", hitDamage, SendMessageOptions.DontRequireReceiver);
	}

	void _SelfDamage()
	{
		float hitDamage = Mathf.Max(blockHP / 2.0f, 1f);

		ApplyDamage(hitDamage);
	}

	void _ApplyBlockCondition()
	{
		if (blockHP <= 0)
		{
			currentBlockCondition = BlockCondition.Broken;
		}
		else if (blockHP > 0.8f * blockStandardHP)
		{
			currentBlockCondition = BlockCondition.Cracked;
		}
		else if (blockHP > 0.3f * blockStandardHP)
		{
			currentBlockCondition = BlockCondition.Poor;
		}
		else
		{
			currentBlockCondition = BlockCondition.Wrecked;
		}
	}

	void _ApplyScore()
	{
		int score = 0;

		if (currentBlockCondition == BlockCondition.Broken)
		{
			if (beforeBlockCondition == BlockCondition.Perfect)
			{
				score = 500;
			}
			else if (beforeBlockCondition == BlockCondition.Cracked)
			{
				score = 300;
			}
			else if (beforeBlockCondition == BlockCondition.Poor)
			{
				score = 100;
			}
			else
			{
				score = 50;
			}
		}
		else
		{
			score = Mathf.Max(100 * ((int)currentBlockCondition - (int)beforeBlockCondition), 10);
		}

		scGameManager.AddScore(score);
	}
	
	void _ApplyBlockEffect()
	{
		if (currentBlockCondition == BlockCondition.Broken)
		{
			Instantiate(blockCrash, transform.position, Quaternion.Euler(0f, 0f, 0f));
			DestroyObject(gameObject);
		}
		else if (beforeBlockCondition == currentBlockCondition)
		{
			// only audio effect
		}
		else
		{
			// sprite and audio effect
			GetComponent<SpriteRenderer>().sprite = blockSprite[(int)currentBlockCondition - 1];
		}
	}


	// Drag Object
	IEnumerator OnMouseDown()
	{
		Debug.Log("block mouse down");
		
		Vector3 scrSpace = Camera.main.WorldToScreenPoint(transform.position);
		Vector3 offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, scrSpace.z));
		
		while (Input.GetMouseButton(0))
		{
			Vector3 curScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, scrSpace.z);
			Vector3 curPosition = Camera.main.ScreenToWorldPoint(curScreenSpace) + offset;
			transform.position = curPosition;
			yield return null;
		}
	}
}
